namespace SimpleWebServices.Web.UI.Html.Validation
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Xml;
    using System.Xml.Serialization;
    using SimpleWebServices;
    using Xunit;

    public sealed class ValidatorSettingsCollectionFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<ValidatorSettingsCollection>()
                .DerivesFrom<object>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .Implements<IEnumerable<ValidatorSettings>>()
                .XmlRoot("validators")
                .Result);
        }

        [Fact]
        public void deserialize()
        {
            string type = typeof(StandardTextValidator).FullName;

            string xml =
                "<validators>" +
                    "<validator display='label' for='input' type='" + type + "'>" +
                        "<data><value name='foo'>bar</value></data>" +
                    "</validator>" +
                    "<foo />" +
                "</validators>";

            ValidatorSettingsCollection obj = xml.Deserialize<ValidatorSettingsCollection>();

            Assert.Equal<int>(1, obj.Count);
        }

        [Fact]
        public void deserializeEmpty()
        {
            ValidatorSettingsCollection obj = "<validators/>".Deserialize<ValidatorSettingsCollection>();

            Assert.Equal<int>(0, obj.Count);
        }

        [Fact]
        public void serialize()
        {
            string type = typeof(StandardTextValidator).FullName;

            ValidatorSettings validator = new ValidatorSettings
            {
                Display = "label",
                For = "input",
                Type = type,
                Data =
                {
                    { "foo", "bar" }
                }
            };

            ValidatorSettingsCollection obj = new ValidatorSettingsCollection();
            obj.Add(validator);

            string xpath = "1=count(/validators/validator[@display='label'][@for='input'][@type='" + type + "']/data/value[@name='foo'][text()='bar'])";

            Assert.True((bool)obj.Serialize().CreateNavigator().Evaluate(xpath));
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new ValidatorSettingsCollection());
        }

        [Fact]
        public void prop_Count()
        {
            Assert.True(new PropertyExpectations(typeof(ValidatorSettingsCollection).GetProperty("Count"))
                .TypeIs<int>()
                .DefaultValueIs(0)
                .Result);
        }

        [Fact]
        public void indexer_string_get()
        {
            ValidatorSettings expected = new ValidatorSettings
            {
                For = "example"
            };

            ValidatorSettingsCollection obj = new ValidatorSettingsCollection();
            obj.Add(expected);

            ValidatorSettings actual = obj["example"];

            Assert.Same(expected, actual);
        }

        [Fact]
        public void indexer_string_get_whenNotFound()
        {
            Assert.Null(new ValidatorSettingsCollection()["example"]);
        }

        [Fact]
        public void indexer_int_get()
        {
            ValidatorSettings expected = new ValidatorSettings();

            ValidatorSettingsCollection obj = new ValidatorSettingsCollection();
            obj.Add(new ValidatorSettings());

            obj[0] = expected;

            ValidatorSettings actual = obj[0];

            Assert.Same(expected, actual);
        }

        [Fact]
        public void indexer_int_get_whenNull()
        {
            ValidatorSettingsCollection obj = new ValidatorSettingsCollection();
            obj.Add(new ValidatorSettings());

            Assert.Throws<ArgumentNullException>(() => obj[0] = null as ValidatorSettings);
        }

        [Fact]
        public void op_Add_ValidatorSettings()
        {
            ValidatorSettings expected = new ValidatorSettings();

            ValidatorSettingsCollection obj = new ValidatorSettingsCollection();
            obj.Add(expected);

            ValidatorSettings actual = obj[0];

            Assert.Same(expected, actual);
        }

        [Fact]
        public void op_Add_ValidatorSettingsNull()
        {
            Assert.Throws<ArgumentNullException>(() => new ValidatorSettingsCollection().Add(null as ValidatorSettings));
        }

        [Fact]
        public void op_Clear()
        {
            ValidatorSettings expected = new ValidatorSettings();

            ValidatorSettingsCollection obj = new ValidatorSettingsCollection();
            obj.Add(expected);

            Assert.NotEmpty(obj);

            obj.Clear();

            Assert.Empty(obj);
        }

        [Fact]
        public void IEnumerable_op_GetEnumerator()
        {
            Assert.NotNull((new ValidatorSettingsCollection() as IEnumerable).GetEnumerator());
        }

        [Fact]
        public void IEnumerableOfT_op_GetEnumerator()
        {
            Assert.NotNull((new ValidatorSettingsCollection() as IEnumerable<ValidatorSettings>).GetEnumerator());
        }

        [Fact]
        public void IXmlSerializable_op_GetSchema()
        {
            Assert.Throws<NotSupportedException>(() => (new ValidatorSettingsCollection() as IXmlSerializable).GetSchema());
        }

        [Fact]
        public void IXmlSerializable_op_ReadXml_XmlReaderNull()
        {
            Assert.Throws<ArgumentNullException>(() => (new ValidatorSettingsCollection() as IXmlSerializable).ReadXml(null as XmlReader));
        }

        [Fact]
        public void IXmlSerializable_op_WriteXml_XmlWriterNull()
        {
            Assert.Throws<ArgumentNullException>(() => (new ValidatorSettingsCollection() as IXmlSerializable).WriteXml(null as XmlWriter));
        }
    }
}